package service

import (
	"bytes"
	"context"
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"github.com/wonderivan/logger"
	"k8s-platform/config"
	"k8s-platform/db"
	"k8s-platform/model"
	"log"
	"os"
	"path/filepath"
	"strings"
)

var Jenkinsjob jenkinsjob

type jenkinsjob struct{}

func (*jenkinsjob) Create(jenkinsjoblist *model.Jenkinsjoblist) (createname string, err error) {

	jenkinsConfigTest := &config.JenkinsConfigTest{}
	mysqlconfig, err := jenkinsConfigTest.ConfigTest()
	if err != nil {
		log.Fatalf("Failed to parse configuration: %v", err)
	}

	ctx := context.Background()
	var config string
	if jenkinsjoblist.Piplelinedata != "" {
		var piplelinedatabyte bytes.Buffer
		xmlerr := xml.EscapeText(&piplelinedatabyte, []byte(jenkinsjoblist.Piplelinedata))
		if xmlerr != nil {
			logger.Error("转义失败"+jenkinsjoblist.JobName, xmlerr)
			return jenkinsjoblist.JobName, errors.New("转义失败" + jenkinsjoblist.JobName + xmlerr.Error())
		}
		config = fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8'?>
	<flow-definition plugin="workflow-job@1360.vc6700e3136f5">
	 <actions/>
	 <description></description>
	 <keepDependencies>false</keepDependencies>
	 <properties>
	   <com.tikal.hudson.plugins.notification.HudsonNotificationProperty plugin="notification@1.17">
	     <endpoints>
	       <com.tikal.hudson.plugins.notification.Endpoint>
	         <protocol>HTTP</protocol>
	         <format>JSON</format>
	         <urlInfo>
	           <urlOrId>%s/jenkins-webhook</urlOrId>
	           <urlType>PUBLIC</urlType>
	         </urlInfo>
	         <event>all</event>
	         <timeout>30000</timeout>
	         <loglines>0</loglines>
	         <buildNotes></buildNotes>
	         <retries>0</retries>
	         <branch>.*</branch>
	       </com.tikal.hudson.plugins.notification.Endpoint>
	     </endpoints>
	   </com.tikal.hudson.plugins.notification.HudsonNotificationProperty>
	 </properties>
	 <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@3806.va_3a_6988277b_2">
	   <script>
	%s
		</script>
	   <sandbox>true</sandbox>
	 </definition>
	 <triggers/>
	 <disabled>false</disabled>
	</flow-definition>`, mysqlconfig.Jenkins_Notifications, piplelinedatabyte.String())

	} else {
		var CIcommandbyte bytes.Buffer
		CIcommandbyteerr := xml.EscapeText(&CIcommandbyte, []byte(jenkinsjoblist.CIcommand))
		if CIcommandbyteerr != nil {
			logger.Error("转义失败"+jenkinsjoblist.JobName, CIcommandbyteerr)
			return jenkinsjoblist.JobName, errors.New("转义失败" + jenkinsjoblist.JobName + CIcommandbyteerr.Error())
		}
		var CDcommandbyte bytes.Buffer
		CDcommandbyteerr := xml.EscapeText(&CDcommandbyte, []byte(jenkinsjoblist.CDcommand))
		if CDcommandbyteerr != nil {
			logger.Error("转义失败"+jenkinsjoblist.JobName, CDcommandbyteerr)
			return jenkinsjoblist.JobName, errors.New("转义失败" + jenkinsjoblist.JobName + CDcommandbyteerr.Error())
		}
		config = fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8'?>
<flow-definition plugin="workflow-job@1360.vc6700e3136f5">
 <actions/>
 <description></description>
 <keepDependencies>false</keepDependencies>
 <properties>
   <com.tikal.hudson.plugins.notification.HudsonNotificationProperty plugin="notification@1.17">
     <endpoints>
       <com.tikal.hudson.plugins.notification.Endpoint>
         <protocol>HTTP</protocol>
         <format>JSON</format>
         <urlInfo>
           <urlOrId>%s/jenkins-webhook</urlOrId>
           <urlType>PUBLIC</urlType>
         </urlInfo>
         <event>all</event>
         <timeout>30000</timeout>
         <loglines>0</loglines>
         <buildNotes></buildNotes>
         <retries>0</retries>
         <branch>.*</branch>
       </com.tikal.hudson.plugins.notification.Endpoint>
     </endpoints>
   </com.tikal.hudson.plugins.notification.HudsonNotificationProperty>
 </properties>
 <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@3806.va_3a_6988277b_2">
   <script>
pipeline {
	agent { label '%s' }
    environment {
        gitlistname = '%s' 
		branche = '%s'
		imagesregion = '%s'
    }
	stages {
	  stage ("代码获取") {
	    steps {
			 sh label: 'init', returnStatus: true, script: 'rm -rf $gitlistname'  
			 sh label: 'git', returnStatus: true, script: 'git clone http://gitlab-ci-token:$Gitlabtoken@%s -b %s'
	    }
	  }

	  stage ("代码质检") {
	   steps {
	     sh label: 'sonar', returnStatus: true, script: 'echo "代码质检"'
	   }
	  }

	  stage ("项目构建") {
	   steps {
	    sh label: 'build', script: 'npm config set registry https://registry.npmmirror.com/'
		sh  '''
		go env -w GO111MODULE=on  
		go env -w GOPROXY=https://goproxy.cn,direct
		cd $gitlistname
		%s
		docker build -t  $harborurl/$imagesregion/$gitlistname:$branche-$BUILD_ID  .
		docker push $harborurl/$imagesregion/$gitlistname:$branche-$BUILD_ID
 		'''
	   }
	  }

	  stage ("项目部署") {
	   steps {
		sh label: 'deploy', returnStatus: true, script: 'echo "开始部署" '
		sh  '''
		cd $gitlistname
		if [ !- f /opt/kubeconfig/yaml/$imagesregion$gitlistname.yaml1 ];then
			filename=$(ls | grep yaml | grep $gitlistname)
			sed -i  "s#image:.*#image: $harborurl/$imagesregion/$gitlistname:$branche-$BUILD_ID#g" $filename
			kubectl --kubeconfig=/opt/kubeconfig/home-k8s apply -f $filename
		else
			cp /opt/kubeconfig/yaml/$imagesregion$gitlistname.yaml .
			sed -i  "s#image:.*#image: $harborurl/$imagesregion/$gitlistname:$branche-$BUILD_ID#g" $imagesregion$gitlistname.yaml
			kubectl --kubeconfig=/opt/kubeconfig/home-k8s apply -f $imagesregion$gitlistname.yaml
		fi
		'''
	   }
	  }
	}
	}
	</script>
   <sandbox>true</sandbox>
 </definition>
 <triggers/>
 <disabled>false</disabled>
</flow-definition>`, mysqlconfig.Jenkins_Notifications, jenkinsjoblist.JenkinslistCIdata, jenkinsjoblist.GitlistName, jenkinsjoblist.Branche, jenkinsjoblist.ImagesRegion, jenkinsjoblist.GitlistUrl, jenkinsjoblist.Branche, CIcommandbyte.String())
	}

	_, err = Jenkins_init.JenkinsClient.CreateJob(ctx, config, jenkinsjoblist.JobName)
	if err != nil {
		logger.Error("创建job失败"+jenkinsjoblist.JobName, err)
		return jenkinsjoblist.JobName, errors.New("创建job失败" + jenkinsjoblist.JobName + err.Error())
	}

	tx := db.DB.Create(&jenkinsjoblist)
	if tx.Error != nil {
		logger.Error(fmt.Sprintf("添加credential失败，%v\n", tx.Error))
		return "nil", errors.New(fmt.Sprintf("添加credential失败，%v\n", tx.Error))
	}

	return "nil", err
}

// Config represents the top-level structure of your JSON.
type Config struct {
	FlowDefinition FlowDefinition `json:"flow-definition"`
}

type FlowDefinition struct {
	XMLName xml.Name `xml:"flow-definition"` // XMLName specifies the root element name.
	Plugin  string   `xml:"plugin,attr"`
	Script  string   `xml:"definition>script"`
}

func (*jenkinsjob) GetConfig(jobname string) (jobconfig string, err error) {

	ctx := context.Background()
	job, err := Jenkins_init.JenkinsClient.GetJob(ctx, jobname)
	if err != nil {
		panic("Failed to get job")
	}
	config, err := job.GetConfig(ctx)
	if err != nil {
		panic("Failed to get job config")
	}

	version_v1 := strings.Replace(config, `version='1.1'`, `version='1.0'`, 1)

	xmlBytes := []byte(version_v1) // Convert string to byte slice.

	var fd FlowDefinition
	err = xml.Unmarshal(xmlBytes, &fd) // Pass byte slice instead of string.
	if err != nil {
		log.Fatalf("Failed to unmarshal XML: %s", err)
	}

	//fmt.Println("Script Value:", fd.Script)

	return fd.Script, err

}

func (*jenkinsjob) UpdateConfig(jobname string, jenkinslistCIdata string, gitlistname string, gitlisturl string, branche string, CIcommand string, CDcommand string, piplelinedata string, ImagesRegion string) (createname string, err error) {

	jenkinsConfigTest := &config.JenkinsConfigTest{}
	mysqlconfig, err := jenkinsConfigTest.ConfigTest()
	if err != nil {
		log.Fatalf("Failed to parse configuration: %v", err)
	}

	ctx := context.Background()
	job, err := Jenkins_init.JenkinsClient.GetJob(ctx, jobname)
	if err != nil {
		panic("Failed to get job")
	}

	var config string
	if piplelinedata != "" {
		var piplelinedatabyte bytes.Buffer
		xmlerr := xml.EscapeText(&piplelinedatabyte, []byte(piplelinedata))
		if xmlerr != nil {
			logger.Error("转义失败"+jobname, xmlerr)
			return jobname, errors.New("转义失败" + jobname + xmlerr.Error())
		}

		config = fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8'?>
<flow-definition plugin="workflow-job@1360.vc6700e3136f5">
 <actions/>
 <description></description>
 <keepDependencies>false</keepDependencies>
 <properties>
   <com.tikal.hudson.plugins.notification.HudsonNotificationProperty plugin="notification@1.17">
     <endpoints>
       <com.tikal.hudson.plugins.notification.Endpoint>
         <protocol>HTTP</protocol>
         <format>JSON</format>
         <urlInfo>
           <urlOrId>%s/jenkins-webhook</urlOrId>
           <urlType>PUBLIC</urlType>
         </urlInfo>
         <event>all</event>
         <timeout>30000</timeout>
         <loglines>0</loglines>
         <buildNotes></buildNotes>
         <retries>0</retries>
         <branch>.*</branch>
       </com.tikal.hudson.plugins.notification.Endpoint>
     </endpoints>
   </com.tikal.hudson.plugins.notification.HudsonNotificationProperty>
 </properties>
 <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@3806.va_3a_6988277b_2">
   <script>
%s
	</script>
   <sandbox>true</sandbox>
 </definition>
 <triggers/>
 <disabled>false</disabled>
</flow-definition>`, mysqlconfig.Jenkins_Notifications, piplelinedatabyte.String())
	} else {
		var CIcommandbyte bytes.Buffer
		CIcommandbyteerr := xml.EscapeText(&CIcommandbyte, []byte(CIcommand))
		if CIcommandbyteerr != nil {
			logger.Error("转义失败"+jobname, CIcommandbyteerr)
			return jobname, errors.New("转义失败" + jobname + CIcommandbyteerr.Error())
		}
		var CDcommandbyte bytes.Buffer
		CDcommandbyteerr := xml.EscapeText(&CDcommandbyte, []byte(CDcommand))
		if CDcommandbyteerr != nil {
			logger.Error("转义失败"+jobname, CDcommandbyteerr)
			return jobname, errors.New("转义失败" + jobname + CDcommandbyteerr.Error())
		}

		config = fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8'?>
<flow-definition plugin="workflow-job@1360.vc6700e3136f5">
 <actions/>
 <description></description>
 <keepDependencies>false</keepDependencies>
 <properties>
   <com.tikal.hudson.plugins.notification.HudsonNotificationProperty plugin="notification@1.17">
     <endpoints>
       <com.tikal.hudson.plugins.notification.Endpoint>
         <protocol>HTTP</protocol>
         <format>JSON</format>
         <urlInfo>
           <urlOrId>%s/jenkins-webhook</urlOrId>
           <urlType>PUBLIC</urlType>
         </urlInfo>
         <event>all</event>
         <timeout>30000</timeout>
         <loglines>0</loglines>
         <buildNotes></buildNotes>
         <retries>0</retries>
         <branch>.*</branch>
       </com.tikal.hudson.plugins.notification.Endpoint>
     </endpoints>
   </com.tikal.hudson.plugins.notification.HudsonNotificationProperty>
 </properties>
 <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@3806.va_3a_6988277b_2">
   <script>
pipeline {
	agent { label '%s' }
    environment {
        gitlistname = '%s' 
		branche = '%s'
		imagesregion = '%s'
    }
	stages {
	  stage ("代码获取") {
	    steps {
			 sh label: 'init', returnStatus: true, script: 'rm -rf $gitlistname'
			 sh label: 'git', returnStatus: true, script: 'git clone http://gitlab-ci-token:$Gitlabtoken@%s -b %s'
	    }
	  }

	  stage ("代码质检") {
	   steps {
	     sh label: 'sonar', returnStatus: true, script: 'echo "代码质检"'
	   }
	  }

	  stage ("项目构建") {
	   steps {
	    sh label: 'build', script: 'npm config set registry https://registry.npmmirror.com/'
		sh  '''
		go env -w GO111MODULE=on  
		go env -w GOPROXY=https://goproxy.cn,direct
		cd $gitlistname
		%s

		docker build -t  $harborurl/$imagesregion/$gitlistname:$branche-$BUILD_ID  .
		docker push $harborurl/$imagesregion/$gitlistname:$branche-$BUILD_ID
 		'''
	   }
	  }

	  stage ("项目部署") {
	   steps {
		sh label: 'deploy', returnStatus: true, script: 'echo "开始部署"'
		sh  '''
		cd $gitlistname
		if [ !- f /opt/kubeconfig/yaml/$imagesregion$gitlistname.yaml1 ];then
			filename=$(ls | grep yaml | grep $gitlistname)
			sed -i  "s#image:.*#image: $harborurl/$imagesregion/$gitlistname:$branche-$BUILD_ID#g" $filename
			kubectl --kubeconfig=/opt/kubeconfig/home-k8s apply -f $filename
		else
			cp /opt/kubeconfig/yaml/$imagesregion$gitlistname.yaml .
			sed -i  "s#image:.*#image: $harborurl/$imagesregion/$gitlistname:$branche-$BUILD_ID#g" $imagesregion$gitlistname.yaml
			kubectl --kubeconfig=/opt/kubeconfig/home-k8s apply -f $imagesregion$gitlistname.yaml
		fi
		'''
	   }
	  }
	}
	}
	</script>
   <sandbox>true</sandbox>
 </definition>
 <triggers/>
 <disabled>false</disabled>
</flow-definition>`, mysqlconfig.Jenkins_Notifications, jenkinslistCIdata, gitlistname, branche, ImagesRegion, gitlisturl, branche, CIcommandbyte.String())
	}

	err = job.UpdateConfig(ctx, config)
	if err != nil {
		panic("Failed to update job config")
	}

	return "updatedConfig", err
}

func (*jenkinsjob) Deletejob(jobname string) (jobnamedata string, err error) {

	ctx := context.Background()
	job, err := Jenkins_init.JenkinsClient.GetJob(ctx, jobname)
	if err != nil {
		panic(err)
	}

	_, err = job.Delete(ctx)
	if err != nil {
		panic(err)
	}

	err = db.DB.Where("job_name = ?", jobname).Delete(&model.Jenkinsjoblist{}).Error
	if err != nil {
		fmt.Println("Failed to delete records:", err)
	} else {
		fmt.Println("Successfully deleted records with name 'a1'")
	}

	return jobname + "删除成功", err
}

type FileName struct {
	Name []string `json:"name"`
}

func (*jenkinsjob) GetYAML() (Yamllist json.RawMessage, err error) {
	//jenkinsConfigTest := &config.JenkinsConfigTest{}
	//mysqlconfig, err := jenkinsConfigTest.ConfigTest()
	//entries, err := os.ReadDir(mysqlconfig.YamlsDir)
	//if err != nil {
	//	fmt.Println(err)
	//	return nil, err
	//}
	//var fileNames []string
	//for _, entry := range entries {
	//	if !entry.IsDir() && filepath.Ext(entry.Name()) == ".yaml" {
	//		fileNames = append(fileNames, entry.Name())
	//	}
	//}
	//
	//yamllist, err := json.Marshal(fileNames)
	//return yamllist, err

	// 1. 获取配置中的 YAML 目录路径（来自 config.YamlsDir）
	yamlDir := config.YamlsDir // 此时 yamlDir 是 "config"（根据你的 var YamlsDir 定义）

	// 2. 读取目录下的所有条目（文件/文件夹）
	entries, err := os.ReadDir(yamlDir)
	if err != nil {
		// 处理目录不存在或读取失败的错误（例如：目录未创建）
		return nil, fmt.Errorf("读取 YAML 目录失败: %v（目录路径：%s）", err, yamlDir)
	}

	// 3. 筛选出 .yaml 后缀的文件
	var fileNames []string
	for _, entry := range entries {
		// 排除文件夹，只保留 .yaml 文件
		if !entry.IsDir() && filepath.Ext(entry.Name()) == ".yaml" {
			fileNames = append(fileNames, entry.Name())
		}
	}

	// 4. 转换为 JSON 格式返回
	yamllist, err := json.Marshal(fileNames)
	return yamllist, err

}
